//
//  MPMarkImageView.m
//  MarkPlatform
//
//  Created by xiao6 on 2018/1/7.
//  Copyright © 2018年 AT. All rights reserved.
//

#import "MPMarkImageView.h"

@implementation MPMarkImageView
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [self setup];
    }
    return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self setup];
    }
    return self;
}
- (void)setup {
    [self addSubview:self.imageView];
    [self addSubview:self.markView];
    
    [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTap:)]];
}
- (void)layoutSubviews {
    [super layoutSubviews];
    [self updateDisplay];
}
- (void)updateDisplay {
    self.imageView.frame = self.bounds;
    self.markView.frame = self.imageView.frame;
    
    if (self.model.type == MPTaskTypeReview && self.imageView.image.size.width > 0 && self.imageView.width > 0) {
        CGFloat ratio = self.imageView.width / self.imageView.image.size.width;
        [self.steps enumerateObjectsUsingBlock:^(MPMarkStep * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            for (MPMarkModel *mark in obj.markModels) {
                CGRect rect;
                rect.origin.x = mark.rect.origin.x * ratio;
                rect.origin.y = mark.rect.origin.y * ratio;
                rect.size.width = mark.rect.size.width * ratio;
                rect.size.height = mark.rect.size.height * ratio;
                mark.viewRect = rect;
            }
        }];
    }
    self.markView.step = self.imageView.image ? self.steps.lastObject : nil;
    [UIView animateWithDuration:0.3f animations:^{
        self.scrollView.zoomScale = self.steps.lastObject.zoomScale;
        self.scrollView.contentOffset = self.steps.lastObject.contentOffset;
    }];
}
- (void)setMaxSize:(CGSize)maxSize {
    _maxSize = maxSize;
    [self invalidateIntrinsicContentSize];
}
- (CGSize)intrinsicContentSize {
    if (!self.imageView.image) {
        return CGSizeZero;
    }
    
    CGSize imgSize = self.imageView.image.size;
    CGRect rect = CGRectZero;
    if (imgSize.width / imgSize.height > self.maxSize.width / self.maxSize.height) {
        rect.size.width = self.maxSize.width;
        rect.size.height = self.maxSize.width * imgSize.height / imgSize.width;
        rect.origin.x = 0;
        rect.origin.y = (self.maxSize.height - rect.size.height) / 2;
    }
    else {
        rect.size.height = self.maxSize.height;
        rect.size.width = self.maxSize.height * imgSize.width / imgSize.height;
        rect.origin.x = (self.maxSize.width - rect.size.width) / 2;
        rect.origin.y = 0;
    }
    return rect.size;
}

- (void)setModel:(MPTaskModel *)model {
    _model = model;
    
    @weakify(self)
    [self.imageView sd_setImageWithURL:[NSURL URLWithEncodeString:_model.url] placeholderImage:nil options:SDWebImageHighPriority | SDWebImageRetryFailed | SDWebImageProgressiveDownload progress:nil completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
        @strongify(self)
        [self invalidateIntrinsicContentSize];
        [self updateDisplay];
    }];
    
    [self clearStep];
    [self setupReviewStepIfNeed];
}

- (void)setupReviewStepIfNeed {
    if (self.model.type != MPTaskTypeReview) {
        return;
    }
    MPMarkStep *step = [[MPMarkStep alloc] init];
    step.zoomScale = self.scrollView.zoomScale;
    step.contentOffset = self.scrollView.contentOffset;
    NSArray<NSString *> *items = [self.model.coordinate componentsSeparatedByString:@";"];
    for (NSString *item in items) {
        if (item.length <= 0) {
            continue;
        }
        NSArray<NSString *> *xywh = [item componentsSeparatedByString:@","];
        if (self.model.way == MPMarkTypePoint) {
            CGPoint point = CGPointZero;
            point.x = [xywh objectSafeAtIndex:0].floatValue;
            point.y = [xywh objectSafeAtIndex:1].floatValue;
            MPMarkModel *mark = [MPMarkModel modelWithPoint:point];
            [step.markModels addObject:mark];
        }
        else {
            CGRect rect = CGRectZero;
            rect.origin.x = [xywh objectSafeAtIndex:0].floatValue;
            rect.origin.y = [xywh objectSafeAtIndex:1].floatValue;
            rect.size.width = [xywh objectSafeAtIndex:2].floatValue;
            rect.size.height = [xywh objectSafeAtIndex:3].floatValue;
            MPMarkModel *mark = [MPMarkModel modelWithRect:rect];
            [step.markModels addObject:mark];
        }
    }
    [self addStep:step];
}
#pragma mark - action
- (void)didTap:(UITapGestureRecognizer *)tap {
    if (self.steps.lastObject.markModels.count >= 1) {
        return;
    }
    if (self.model.way == MPMarkTypeRect) {
        CGRect rect = CGRectZero;
        rect.origin = [tap locationInView:self];
        rect = CGRectInset(rect, -40, -40);
        [self addStepWithMark:[MPMarkModel modelWithRect:rect]];
    }
    else {
        [self addStepWithMark:[MPMarkModel modelWithPoint:[tap locationInView:self]]];
    }
}
- (void)addStepWithMark:(MPMarkModel *)mark {
    MPMarkStep *step = [[MPMarkStep alloc] init];
    step.zoomScale = self.scrollView.zoomScale;
    step.contentOffset = self.scrollView.contentOffset;
    if (self.steps.lastObject.markModels.count > 0) {
        if (mark.way == MPMarkTypePoint) {
            [step.markModels addObjectsFromArray:self.steps.lastObject.markModels];
        }
    }
    if (mark) {
        [step.markModels addObject:mark];
    }
    [self addStep:step];
}
- (void)addStep:(MPMarkStep *)step {
    if (!step) {
        return;
    }
    [self.steps addObject:step];
    self.nextSteps = nil;
    [self updateDisplay];
    !self.notifyUpdateDisplay ?: self.notifyUpdateDisplay(self);
}
- (void)preStep {
    MPMarkStep *step = self.steps.lastObject;
    if (!step) {
        return;
    }
    [self.steps removeObject:step];
    [self.nextSteps addObject:step];
    [self updateDisplay];
    !self.notifyUpdateDisplay ?: self.notifyUpdateDisplay(self);
}
- (void)nextStep {
    MPMarkStep *step = self.nextSteps.lastObject;
    if (!step) {
        return;
    }
    [self.nextSteps removeObject:step];
    [self.steps addObject:step];
    [self updateDisplay];
    !self.notifyUpdateDisplay ?: self.notifyUpdateDisplay(self);
}
- (void)clearStep {
    self.steps = nil;
    self.nextSteps = nil;
    [self updateDisplay];
    !self.notifyUpdateDisplay ?: self.notifyUpdateDisplay(self);
}
- (NSString *)stepCoordinate {
    return [self.steps.lastObject stepCoordinateWithScale:self.imageView.image.size.width / self.imageView.width];
}

#pragma mark - getter
- (UIImageView *)imageView {
    if (!_imageView) {
        _imageView = [[UIImageView alloc] init];
    }
    return _imageView;
}
- (MPMarkView *)markView {
    if (!_markView) {
        _markView = [[MPMarkView alloc] init];
        @weakify(self)
        _markView.rectDidChange = ^(MPMarkView *view, CGRect rect) {
            @strongify(self)
            [self addStepWithMark:[MPMarkModel modelWithRect:rect]];
        };
    }
    return _markView;
}
- (NSMutableArray<MPMarkStep *> *)steps {
    if (!_steps) {
        _steps = [NSMutableArray array];
    }
    return _steps;
}
- (NSMutableArray<MPMarkStep *> *)nextSteps {
    if (!_nextSteps) {
        _nextSteps = [NSMutableArray array];
    }
    return _nextSteps;
}
@end
